package org.ala.tiktools.redis;

import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;

import org.ala.tiktools.redis.config.ConfigItem;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.InitializingBean;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Transaction;

/**
 * redis工具类
 *
 * @author ala
 * @date 2024-11-27 14:47
 */
public class RedisTool implements InitializingBean {

    /**
     *  redis连接池
     */
    protected JedisPool pool;

    /**
     *  redis配置项
     */
    protected ConfigItem config;


    @Override
    public void afterPropertiesSet() throws Exception {
        initPool();
    }
    /**
     *  初始化连接池
     */
    protected void initPool() {
        GenericObjectPoolConfig<Jedis> poolConfig = new GenericObjectPoolConfig<>();
        poolConfig.setMaxIdle(config.getPoolIdle());
        poolConfig.setMaxTotal(config.getPoolMax());

        pool = new JedisPool(poolConfig,
                config.getHost(), config.getPort(), config.getTimeout(),
                config.getPassword(),
                config.getDatabase());
    }


    /**
     *  在redis作用于内工作
     */
    public void withJedis(Consumer<Jedis> con) {
        //  借出redis实例
        Jedis jedis = pool.getResource();
        try {
            con.accept(jedis);
        } finally {
            //  还回
            pool.returnResource(jedis);
        }
    }
    /**
     *  在redis作用于内工作
     */
    public <R> R withJedis(Function<Jedis, R> fun) {
        //  借出redis实例
        Jedis jedis = pool.getResource();
        try {
            return fun.apply(jedis);
        } finally {
            //  还回
            pool.returnResource(jedis);
        }
    }


    /**
     *  跑批
     */
    public List<Object> withBatch(Consumer<Pipeline> con) {
        return withJedis(jedis -> {
            Pipeline p = jedis.pipelined();
            con.accept(p);
            return p.syncAndReturnAll();
        });
    }


    /**
     *  跑事务
     */
    public List<Object> withTransaction(Consumer<Transaction> con) {
        return withJedis(jedis -> {
            Transaction tx = jedis.multi();
            con.accept(tx);
            return tx.exec();
        });
    }


    public void setPool(JedisPool pool) {
        this.pool = pool;
    }

    public ConfigItem getConfig() {
        return config;
    }

    public void setConfig(ConfigItem config) {
        this.config = config;
    }

    public JedisPool getPool() {
        return pool;
    }


}
